<?php
/**
 *异常处理控制器
 */
class ErrorController extends Controller_Base {

	public function errorAction() {
		$errors = $this->_getParam('error_handler');
		if (!$errors || !$errors instanceof ArrayObject) {
			return;
		}

		$exception = $errors->exception;
		$exceptionMessage = $exception->getMessage();

		//用户自己抛出的不敏感的应用程序错误提示异常
		if ($errors->type == "EXCEPTION_OTHER" && $exception->getCode() == -500) {
			$this->smarty->assign('noticeMessage', $exceptionMessage);
			$this->smarty->display('notice.tpl');
		} else {
			$exceptionType = get_class($exception);
			$exceptionFilename = $exception->getFile();
			$exceptionLineNumber = $exception->getLine();
			$exceptionTrace = $exception->getTrace();
			$requestParameters = $errors->request->getParams();
			$requestParameters = print_r($requestParameters, true);

			$this->logException($exception);

			if (str_ireplace(array('off', 'none', 'no', 'false', 'null'), '', ini_get('display_errors'))) {
				$this->smarty->assign('requestParameters', $requestParameters);
				$this->smarty->assign('exceptionType', $exceptionType);
				$this->smarty->assign('exceptionMessage', $exceptionMessage);
				$this->smarty->assign('exceptionFilename', $exceptionFilename);
				$this->smarty->assign('exceptionLineNumber', $exceptionLineNumber);
				$this->smarty->assign('exceptionTrace', $exceptionTrace);
				$this->smarty->display('error.tpl');
			}
		}

	}

	public function logException($exception) {
		$traceline = "#%s %s(%s): %s(%s)";
		$msg = "PHP Fatal error:  Uncaught exception '%s' with message '%s' in %s:%s\nStack trace:\n%s\n  thrown in %s on line %s";

		// alter your trace as you please, here
		$trace = $exception->getTrace();
		foreach ($trace as $key => $stackPoint) {
			// I'm converting arguments to their type
			// (prevents passwords from ever getting logged as anything other than 'string')
			$trace[$key]['args'] = array_map('gettype', $trace[$key]['args']);
		}

		// build your tracelines
		$result = array();
		foreach ($trace as $key => $stackPoint) {
			$result[] = sprintf(
				$traceline,
				$key,
				$stackPoint['file'],
				$stackPoint['line'],
				$stackPoint['function'],
				implode(', ', $stackPoint['args'])
			);
		}
		// trace always ends with {main}
		$result[] = '#' . ++$key . ' {main}';

		// write tracelines into main template
		$msg = sprintf(
			$msg,
			get_class($exception),
			$exception->getMessage(),
			$exception->getFile(),
			$exception->getLine(),
			implode("\n", $result),
			$exception->getFile(),
			$exception->getLine()
		);

		$log = new Log();
		$log->record($msg, Log::ERR);
	}
}
